#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiringPi.h>
#include <unistd.h>
#include <pthread.h>
#include "uartTool.h"
#include "garbage_ID.h"
#include "pwm.h"
#include "mOled.h"
#include "socket.h"

static int detect_process(const char *process_name) //判断摄像头线程编号
{
	int n = -1;
	FILE *strm;
	char buf[128] = {0};
	sprintf(buf, "ps -ax | grep %s|grep -v grep", process_name);
	if ((strm = popen(buf, "r")) != NULL)
	{
		if (fgets(buf, sizeof(buf), strm) != NULL)
		{
			n = atoi(buf);
		}
	}
	else
	{
		return -1;
	}
	pclose(strm);
	return n;
}


int serial_fd = -1;
pthread_cond_t cond;
pthread_mutex_t mutex;

void *pGetVoice(void *arg){
	unsigned char buffer[6] = {0xAA, 0X55, 0x00, 0x00, 0x55, 0xAA};
	int len = 0;
	printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
	if (-1 == serial_fd)
	{
		printf("%s|%s|%d: open serial failed\n", __FILE__, __func__, __LINE__);
		pthread_exit(0);
	}

	while(1){
		len = serialGetstring(serial_fd, buffer);
		printf("%s|%s|%d, len=%d\n", __FILE__, __func__, __LINE__,len);
		if(len > 2 && buffer[2] == 0x46){
			printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
			pthread_mutex_lock(&mutex);
			buffer[2] = 0x00;
			pthread_cond_signal(&cond);
			pthread_mutex_unlock(&mutex);			
		}

	}
	pthread_exit(0);
}

void *psend_voice(void *arg){
	pthread_detach(pthread_self());
	unsigned char *buffer = (unsigned char *)arg;
	if (-1 == serial_fd)
	{
		printf("%s|%s|%d: open serial failed\n", __FILE__, __func__, __LINE__);
		pthread_exit(0);
	}
	if (NULL != buffer)
	{
		serialSendstring(serial_fd, buffer, 6);
	}

	pthread_exit(0);
}


void *popen_trash_can(void *arg){
	pthread_detach(pthread_self());
	unsigned char *buffer = (unsigned char *)arg;
	if (buffer[2] == 0x43)
	{
		printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
		pwm_write(PWM_RECOVERABLE_GARBAGE);
		delay(2000);
		pwm_stop(PWM_RECOVERABLE_GARBAGE);
	}
	pthread_exit(0);
}

void *poled_show(void *arg){
	pthread_detach(pthread_self());
	myoled_init();
	oled_show(arg);
	pthread_exit(0);
}

void *pCategory(void *arg){
	unsigned char buffer[6] = {0xAA, 0x55, 0x00, 0x00, 0X55, 0xAA};
	char *category = NULL;
	pthread_t send_voice_tid, trash_tid, oled_tid;

	while(1){
		pthread_mutex_lock(&mutex);
		pthread_cond_wait(&cond, &mutex);
		pthread_mutex_unlock(&mutex);

		printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);

		buffer[2] = 0x00;
		system(WGET_CMD);

		if(access(GARBAGE_FILE, F_OK)==0){
			category = garbageClassID(category);
			if (strstr(category, "干垃圾"))
			{
				buffer[2] = 0x41;
			}
			else if (strstr(category, "湿垃圾"))
			{
				buffer[2] = 0x42;
			}
			else if (strstr(category, "可回收垃圾"))
			{
				printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
				buffer[2] = 0x43;
			}
			else if (strstr(category, "有害垃圾"))
			{
				buffer[2] = 0x44;
			}
			else
			{
				buffer[2] = 0x45;
			}
			// 开语音播报线程
			pthread_create(&trash_tid, NULL, psend_voice, (void *)buffer);
			// 开垃圾桶开关
			pthread_create(&send_voice_tid, NULL, popen_trash_can, (void *)buffer);
			// OLED显示屏幕
			pthread_create(&oled_tid, NULL, poled_show, (void *)buffer);

			remove(GARBAGE_FILE);
		}

	}
	pthread_exit(0);
}


void *pSocket(void *arg){
	int s_fd = -1;
	int c_fd = -1;
	char buffer[6];
	int nread = -1;

	struct sockaddr_in c_addr;
	memset(&c_addr,0,sizeof(struct sockaddr_in)); 
	s_fd = socket_init(IPADDR, IPPORT);
	printf("%s|%s|%d:s_fd=%d\n", __FILE__, __func__, __LINE__, s_fd);
	if (-1 == s_fd)
	{
		pthread_exit(0);
	}

	int clen = sizeof(struct sockaddr_in);
	while(1){
		c_fd = accept(s_fd, (struct sockaddr *)&c_addr, &clen);

		int keepalive = 1; // 开启TCP KeepAlive功能
		int keepidle = 5; // tcp_keepalive_time 3s内没收到数据开始发送心跳包
		int keepcnt = 3; // tcp_keepalive_probes 每次发送心跳包的时间间隔,单位秒
		int keepintvl = 3; // tcp_keepalive_intvl 每3s发送一次心跳包
		setsockopt(c_fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive,sizeof(keepalive));
		setsockopt(c_fd, SOL_TCP, TCP_KEEPIDLE, (void *) &keepidle, sizeof(keepidle));
		setsockopt(c_fd, SOL_TCP, TCP_KEEPCNT, (void *)&keepcnt, sizeof(keepcnt));
		setsockopt(c_fd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepintvl, sizeof(keepintvl));
		printf("%s|%s|%d: Accept a connection from %s:%d\n", __FILE__, __func__,__LINE__, inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port));
		while(1)
		{
			memset(buffer, 0, sizeof(buffer));
			nread = recv(c_fd, buffer, sizeof(buffer), 0); //n_read = read(c_fd,buffer, sizeof(buffer));
			printf("%s|%s|%d:nread=%d, buffer=%s\n", __FILE__, __func__,__LINE__, nread, buffer);
			if (nread > 0)
			{
				if (strstr(buffer, "open"))
				{
					pthread_mutex_lock(&mutex);
					pthread_cond_signal(&cond);
					pthread_mutex_unlock(&mutex);
				}
			}
			else if(0 == nread || -1 == nread)
			{
				break;
			}
		}
		close(c_fd);
	}
	pthread_exit(0);
}

int main(){

	unsigned char buffer[6] = {0xAA, 0X55, 0x00, 0x00, 0x55, 0xAA};
	int len = 0;
	int ret = -1;
	char *category = NULL;

	garbage_init();
	wiringPiSetup();

	ret = detect_process("mjpg_streamer");
	if ( 0 == ret)
	{
		goto END;
	}

	serial_fd = myserialOpen(SERIAL_DEV, BAUD);
	if (0 == serial_fd)
	{
		goto END;
	}

	printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
	pthread_t get_voice_tid, category_tid,socket_tid;

	// 开语音线程
	pthread_create(&get_voice_tid, NULL, pGetVoice, NULL);
	// 开阿里云交互线程
	printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
	pthread_create(&category_tid, NULL, pCategory, NULL);
	// 打开TCP网络连接
	pthread_create(&socket_tid, NULL, pSocket, NULL);

	pthread_join(get_voice_tid, NULL);
	pthread_join(category_tid, NULL);
	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&cond);

	close(serial_fd);
END:
	garbage_final();
	return 0;
}
